package com.blockchain.console.servlets.financial.bzc;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.blockchain.common.enums.CoinType;
import com.blockchain.common.enums.XlbZcStatus;
import com.blockchain.console.service.common.entity.EthereumEntity;
import com.blockchain.console.service.financial.BManage;
import com.blockchain.console.service.financial.XlbZcManage;
import com.blockchain.console.service.financial.entity.BEntity;
import com.blockchain.console.service.financial.entity.NeoResultEntity;
import com.blockchain.console.service.financial.entity.NeoTransactionEntity;
import com.blockchain.console.service.financial.entity.TtQbEntity;
import com.blockchain.console.servlets.financial.AbstractFinancialServlet;
import com.blockchain.console.servlets.util.BtcUtil;
import com.blockchain.console.servlets.util.EthereumUtil;
import com.blockchain.console.servlets.util.JsonUtil;
import com.blockchain.console.servlets.util.NEOUtil;
import com.blockchain.framework.http.servlet.annotation.Right;
import com.blockchain.framework.resource.PromptLevel;
import com.blockchain.framework.service.ServiceSession;
import com.blockchain.framework.service.exception.ParameterException;
import com.blockchain.util.StringHelper;
import com.blockchain.util.parser.EnumParser;
import com.blockchain.util.parser.IntegerParser;

import net.sf.json.JSONObject;

@Right(id = "C_FINANCIAL_XLBZCSH", name = "虚拟币转出-转出审核")
public class ZbZcSh extends AbstractFinancialServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void processGet(HttpServletRequest request, HttpServletResponse response, ServiceSession serviceSession)
			throws Throwable {
		BManage manage = serviceSession.getService(BManage.class);
		int id = IntegerParser.parse(request.getParameter("id"));
		BEntity t = manage.getBzc(id);
		request.setAttribute("result", t);
		forwardView(request, response, getClass());
	}

	@Override
	protected void processPost(final HttpServletRequest request, HttpServletResponse response,
			ServiceSession serviceSession) throws Throwable {
		try {
			BManage manage = serviceSession.getService(BManage.class);
			XlbZcManage zcmanage = serviceSession.getService(XlbZcManage.class);
			XlbZcStatus status = EnumParser.parse(XlbZcStatus.class, request.getParameter("zczt"));
			int id = IntegerParser.parse(request.getParameter("id"));
			String bz = request.getParameter("bz");// 备注
			BEntity t = manage.getBzc(id);// 虚拟币转出信息
			
			TtQbEntity pt = manage.getPt(t.bid);// 平台钱包信息
			if (status != null && status == XlbZcStatus.QZZC) {
				manage.updateBzcSh(id, status, bz);
				zcmanage.add(id, "otc");
			}
			if (status != null && status == XlbZcStatus.ZCSB) {
				manage.updateBzcSh(id, status, bz);// 失败
			}
			if (status != null && status == XlbZcStatus.ZCCG) {
				if (!StringHelper.isEmpty(pt.sy) && !StringHelper.isEmpty(pt.dz)) {
					if(CoinType.SWT.name().equals(t.cointype)){
						swtTurnOut(manage, zcmanage, status, id, bz, t, pt);
					}
				}
				if (CoinType.BTC.name().equals(t.cointype)) {
					btcTurnOut(manage, zcmanage, status, id, bz, t, pt);
				}

				if (CoinType.ETH.toString().equals(t.cointype)) {
					ethTurnOut(manage, zcmanage, status, id, bz, t, pt);
				}

				if (!"NEO".equals(t.b_ywm) && CoinType.NEO.toString().equals(t.cointype)) {
					neoTurnOut(manage, zcmanage, status, id, bz, t, pt);
				}
			}
			sendRedirect(request, response, getController().getURI(request, BzcList.class) + "?zczt=" + XlbZcStatus.SHTG);
		} catch (Throwable e) {
			e.printStackTrace();
			prompt(request, response, PromptLevel.ERROR, e.getMessage());
			processGet(request, response, serviceSession);
		}
	}

	private void neoTurnOut(BManage manage, XlbZcManage zcmanage, XlbZcStatus status, int id, String bz, BEntity t,
			TtQbEntity pt) throws Throwable {
		if (StringHelper.isEmpty(pt.ip) || StringHelper.isEmpty(pt.prot)) {
			throw new ParameterException("钱包参数异常。");
		}

		NeoResultEntity entity = NEOUtil.getBlockCount(pt.ip, pt.prot);
		if (entity.error != null) {
			throw new ParameterException("钱包链接失败" + entity.error);
		} else {
			BigDecimal balance = NEOUtil.getBalance(pt.ip, pt.prot, t.contractAddress);
			BigDecimal fee = new BigDecimal("0.00006");
			if (balance.compareTo(t.zcsl) == 1) {
				if (balance.compareTo(fee) == -1) {
					throw new ParameterException("手续费不足 ,当前币种余额为:" + balance);
				} else {
					manage.updateBzcSh(id, status, bz);
					NeoTransactionEntity transactionResult = NEOUtil.sendTransaction(pt.ip, pt.prot,
						t.contractAddress, t.zcdz, t.zcsl.toString());
					if (transactionResult != null
							&& !StringHelper.isEmpty((String) transactionResult.txid)) {
						zcmanage.add(id, transactionResult.txid);
					}
				}
			} else {
				throw new ParameterException(t.b_ywm + "余额不足 ,当前余额为:" + balance);
			}
		}
	}

	private void ethTurnOut(BManage manage, XlbZcManage zcmanage, XlbZcStatus status, int id, String bz, BEntity t,
			TtQbEntity pt) throws Throwable {
		if ("ETH".equals(t.b_ywm)) {
			// ETH系列转出
			if (StringHelper.isEmpty(pt.ip) || StringHelper.isEmpty(pt.prot)
					|| StringHelper.isEmpty(pt.username) || StringHelper.isEmpty(pt.pass)) {
				throw new ParameterException("钱包参数异常。");
			}

			BigDecimal zcsl = t.zcsl.multiply(new BigDecimal("1000000000000000000"));
			System.out.println(pt.ip);
			System.out.println(t.zcsl);
			System.out.println(EthereumUtil.encodeDec(zcsl));
			System.out.println(t.contractAddress);
			EthereumEntity entity = EthereumUtil.eth_protocolVersion(pt.ip, pt.prot);
			if (entity.error != null) {
				throw new ParameterException("钱包链接失败" + entity.error);
			} else {
				// 查询余额是否充足
				BigDecimal balance = EthereumUtil.eth_getBalance(pt.ip, pt.prot, pt.username);
				if (balance.compareTo(t.zcsl) == 1) {
					BigDecimal fee = new BigDecimal("0.00006");
					if (balance.compareTo(fee) == -1) {
						throw new ParameterException("手续费不足 ,当前以太坊余额为:" + balance);
					} else {
						manage.updateBzcSh(id, status, bz);// 保存状态为转出
						EthereumUtil.personal_unlockAccount(pt.ip, pt.prot, pt.username, pt.pass);
						EthereumEntity transactionResult = EthereumUtil.eth_sendTransaction(pt.ip, pt.prot,
								pt.username, EthereumUtil.encodeDec(zcsl), t.zcdz, null);
						
						if (transactionResult.result != null
								&& !StringHelper.isEmpty((String) transactionResult.result)) {
							zcmanage.add(id, (String) transactionResult.result);// 成功保存交易哈希值
						}
					}
				} else {
					throw new ParameterException(t.b_ywm + "余额不足 ,当前余额为:" + balance);
				}
			}
		}

		if (!"ETH".equals(t.b_ywm) && CoinType.ETH.toString().equals(t.cointype)) {// ETH系列转出
			if (StringHelper.isEmpty(pt.ip) || StringHelper.isEmpty(pt.prot)
					|| StringHelper.isEmpty(pt.username) || StringHelper.isEmpty(pt.pass)) {
				throw new ParameterException("钱包参数异常。");
			}

			BigDecimal zcsl = t.zcsl.multiply(new BigDecimal(t.unit));
			String zcValue = EthereumUtil.fill_zero(EthereumUtil.encodeDec(zcsl));
			String zcAddress = EthereumUtil.fill_zero(t.zcdz);
			String data = t.methodId + zcAddress + zcValue;
			System.out.println(pt.ip);
			System.out.println(t.zcsl);
			System.out.println(EthereumUtil.encodeDec(t.zcsl));
			System.out.println(t.contractAddress);
			System.out.println(data);
			EthereumEntity entity = EthereumUtil.eth_protocolVersion(pt.ip, pt.prot);
			if (entity.error != null) {
				throw new ParameterException("钱包链接失败" + entity.error);
			} else {
				// 查询余额是否充足
				BigDecimal balance = EthereumUtil.eth_getBalance(pt.ip, pt.prot, pt.username);
				BigDecimal contract_balance = EthereumUtil.contract_getBalance(pt.ip, pt.prot,
						t.contractAddress, pt.username, t.unit);
				BigDecimal fee = new BigDecimal("0.00006");
				if (contract_balance.compareTo(t.zcsl) == 1) {
					if (balance.compareTo(fee) == -1) {
						throw new ParameterException("手续费不足 ,当前以太坊余额为:" + balance);
					} else {
						manage.updateBzcSh(id, status, bz);// 保存状态为转出
						EthereumUtil.personal_unlockAccount(pt.ip, pt.prot, pt.username, pt.pass);
						EthereumEntity transactionResult = EthereumUtil.eth_sendTransaction(pt.ip, pt.prot,
								pt.username, "0x0", t.contractAddress, data);
						if (transactionResult.result != null
								&& !StringHelper.isEmpty((String) transactionResult.result)) {
							zcmanage.add(id, (String) transactionResult.result);// 成功保存交易哈希值
						}
					}
				} else {
					throw new ParameterException(t.b_ywm + "余额不足 ,当前余额为:" + balance);
				}
			}
		}
	}

	private void btcTurnOut(BManage manage, XlbZcManage zcmanage, XlbZcStatus status, int id, String bz, BEntity t,
			TtQbEntity pt) throws SQLException, Throwable, Exception {
		BigDecimal ptzhky;
		if (StringHelper.isEmpty(pt.ip) || StringHelper.isEmpty(pt.prot)
				|| StringHelper.isEmpty(pt.username) || StringHelper.isEmpty(pt.pass)) {
			throw new ParameterException("钱包参数异常。");
		}
		
		ptzhky = BtcUtil.getBtcYe(pt.ip, pt.prot, pt.username, pt.pass);// btc系列余额
		if (ptzhky.compareTo(t.zcsl) < 0) {
			throw new ParameterException("平台钱包余额不足。");
		}
		manage.updateBzcSh(id, status, bz);// 转出BTC系列
		Object[] test = new Object[] { t.zcdz, t.zcsl };
		String r = BtcUtil.post("sendtoaddress", JsonUtil.GsonString(test), pt.ip, pt.prot, pt.username,
				pt.pass);
		Map<String, Object> reault_map = JsonUtil.GsonToMaps(r);
		String reault_map_result = reault_map.get("result").toString();
		if (!StringHelper.isEmpty(reault_map_result)) {
			zcmanage.add(id, reault_map_result);// 成功保存交易哈希值
		}
		System.out.println("BTC(" + t.b_ywm + ")系列转出返回信息：" + r);
	}

	private void swtTurnOut(BManage manage, XlbZcManage zcmanage, XlbZcStatus status, int id, String bz, BEntity t,
			TtQbEntity pt) throws SQLException, Throwable {
		BigDecimal ptzhky;
		if("TCC".equals(t.b_ywm)){
			t.b_ywm="6CAB220FC47B66486AC27F3A91A0BA5A6003A860";//TCC——currency
		}
		ptzhky = BtcUtil.getSwtYe(t.b_ywm, pt.dz, t.ip);// SWT钱信息
		if (ptzhky.compareTo(t.zcsl) < 0) {
			throw new ParameterException("平台钱包余额不足。");
		}
		manage.updateBzcSh(id, status, bz);// 转出SWT
		String s = zcmanage.getZb(pt.dz, pt.sy, t.zcsl, t.b_ywm, t.zcdz, t.ip);
		JSONObject jsonObject = JSONObject.fromObject(s);
		boolean success = jsonObject.getBoolean("success");
		if (success) {
			String hash = jsonObject.getString("hash");
			zcmanage.add(id, hash);// 成功保存交易哈希值
		}
		System.out.println("SWT("+t.b_ywm+")转出返回信息" + s);
	}

}
